home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
ask
/
gmoji
/
source
/
gmoji.s
< prev
Wrap
Text File
|
2000-02-16
|
21KB
|
864 lines
*********************************************************************
* テキスト文字読み取りツール
* GMOJI
* Copyright (C) 1997-98,2000 by AIG-Soft
*********************************************************************
.include defines.mac
.include pspdef.mac
.include skey.mac
.include ksd.mac
.include gmd.mac
.lall * マクロを展開して表示する(主にデバッグ用)
OCUR equ $0000_ffff * 元々のカーソル形状
* 0ライン目から$ff
FCUR equ $0008_ffff * 普通モードカーソル
* 8ライン目から$ff
HCUR equ $000c_cccc * 半角モードカーソル
* 12ライン目から$cc
*********************************************************************
* 常駐ルーチン
*********************************************************************
* 年号をわざわざテキストでなしにバイナリー化しているのは、テキストのみより
* 誤った一致をしにくいから
.text
.even
KEEP_START:
* 常駐確認用識別子
id: .dc.b 'GetMoji V1.4',20,$00,'AIG-Soft',0
*********************************************************************
* ワーク1
*********************************************************************
.even
* 外部プログラム定義 : Opt.1+TABで起動
ExtFunc: .dc.b .low.(SKtab>>8) * 起動キー(スキャンコード)
.dc.b SKopt1 * シフト状態
.dc.l GMOJI * 起動アドレス
.dc.l 0 * 予約
OutFile: * 全画面一気ファイル書き出し時のファイル名
.dc.b 'Gamen.gmd',0 * 5+1+3+1バイト
OutFileEnd:
.ds.b 96-(5+1+3+1) * 全体で96バイト確保
* 将来のファイル名変更機能追加のための布石
.even
AdGMDAPI: .dc.l 0 * GMDのAPIアドレス
AdKSDAPI: .dc.l 0 * KSDのAPIアドレス
mode .dc.b 0 * 読みとりモード 0=普通 , $ff=半角化(for ASK)
cur .dc.b 0 * 初期のカーソル状態
CurPTRN: * 半角モード時のカーソル形状
.dc.b $00,$00,$00,$00,$00,$00,$00,$00
.dc.b $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
.even
*********************************************************************
* 本来外部にあるべきルーチン
*********************************************************************
GMDAPI0 macro no
moveq.l #no,d0 * コマンドセット
bsr GMDCallAPI0 * GMD API呼びだし
endm
KSDAPI0 macro no
moveq.l #no,d0 * コマンドセット
bsr KSDCallAPI0 * KSD API呼びだし
endm
KSDCallAPI0: * API呼びだし
* d0.b=コマンド
move.l AdKSDAPI(pc),-(sp)
rts * 飛び先からrtsする
GMDCallAPI0: * API呼びだし
* d0.b=コマンド
move.l AdGMDAPI(pc),-(sp)
rts * 飛び先からrtsする
*********************************************************************
ModeSet macro
* 初期設定
* GMD設定(使用直前に設定する)
lea Writer(pc),a2
GMDAPI0 GMD_SetWriter * Writer設定
move.l d0,Wt
sub.l a2,a2 * デフォルト設定
GMDAPI0 GMD_SetGroup * Group設定
move.l d0,Gp
move.l CSRX.w,xy0 * 元のカーソル位置保存
* マウス処理
IOCS _MS_STAT * マウスカーソル表示モード保存
move.w d0,msc * 0=off , -1=on
IOCS _MS_CUROF * マウスカーソルは消す
* カーソル処理
move.b CSRSWITCH.w,cur * カーソル表示状態保存
IOCS _OS_CURON * カーソル表示
moveq.l #1,d1
IOCS _B_CONMOD * カーソル点滅停止(IOCS.X)
*
* ASK判定(V1.21)
* ASKがない時は一部処理を無効にするため(ASKの内部ルーチンを使うから)
st mode * OFFで$FFにする
pea 50.w
DOS _KNJCTRL * version check
addq.l #4,sp
tst.l d0 * ASK none = -1
smi fask * ASKが無いならfask!=0
bmi 10f * ASKがない
* モード設定 (V1.2でASK自動判別にする)
* ノーマルASKでfpcallを使って変換ラインのON/OFFを見分ける(Thanks FDSさん)
pea 8.w
DOS _KNJCTRL
move.l d0,-(sp)
pea 7.w
DOS _KNJCTRL
lea 12(sp),sp
tst.l d0 * 0ならASKはOFF,2ならON状態
seq mode * OFFで$FFにする
10: bsr MODE_SET * ここで反転されるので↑で良い
* V1.12まで
*clr.b mode * 初期は常に普通取り込み
*bsr NormalWaku
*
IOCS _ONTIME * 枠点滅初期時間
move.l d0,tm0
endm
ModeReset macro
* 戻し
local L1,L2
* カーソルを元に戻す
tst.b cur
bne L1
IOCS _OS_CUROF * カーソル非表示
L1: moveq.l #0,d1
IOCS _B_CONMOD * カーソル点滅(IOCS.X)
moveq.l #0,d0 * 枠パターン:消去
bsr CurWaku * V1.12
* マウスカーソルを元に戻す
moveq.l #_MS_CUROF,d0
tst.w msc
beq L2
moveq.l #_MS_CURON,d0
L2: trap #15 * IOCS
* GMDを戻す
move.l Wt(pc),d0
GMDAPI0 GMD_SetWriter * Writer戻し
move.l Gp(pc),d0
GMDAPI0 GMD_SetGroup * Group戻し
endm
*---------------------------------------------------
GMOJI:
* メインルーチン
* KSDからの起動なのでスーパーバイザーモードで動く
movem.l d3-d7/a3-a6,-(sp) * レジスタ保存
ModeSet * APIなどの設定
*
1: move.l CSRXMAX.w,d5 * テキスト画面の幅-1:xm|ym
swap d5
move.l CSRX.w,d6 * カーソル位置 : x|y
swap d6 * xの方がよく処理されるのでxをlowに置く
2: * キー入力
IOCS _ONTIME * 時間
move.l d0,d1 * 保存
sub.l tm0,d0 * t-tm0
cmp.l #17,d0 * 枠点滅(1/6≒17/100sec)
bls 3f
bsr WakuRev * 枠反転
move.l d1,tm0
3: KSDAPI0 KSD_B_KEYSNS * キー入力センス
tst.w d0 * 入力有り?
beq 2b * No
* キー入力がある
KSDAPI0 KSD_B_KEYINP * キー入力
move.w d0,d1 * -> d1.w
KSDAPI0 KSD_B_SFTSNS * シフト状態 -> d0.w
moveq.l #0,d7 * 継続の印
* キー入力別処理へ飛ぶ
lea TJTable(pc),a0
@@: move.l (a0)+,d2 * jump|code
beq 2b * -> end of table : 操作キーでない -> 戻る
cmp.w d1,d2 * =code?
bne @b * no
swap d2 * d0=jump
jsr -4(a0,d2.w)
* <- ここに戻ってくる(d7.l=0:継続,<>0:終了)
* カーソル移動
swap d6 * y|x -> x|y
bmi @f * d6.l=-1のときはカーソルはすでに移動されているので処理しない
cmp.l CSRX.w,d6
beq @f * 移動はない
* カーソルoffは移動時の瞬間だけにしてカーソルが見えなくなるのを最小限にする
IOCS _B_CUROFF * カーソルを操作するため
move.l d6,CSRX.w
IOCS _B_CURON * カーソル戻し
@@: tst.l d7 * 終了?
beq 1b * No -> 継続
*
ModeReset * 戻し
movem.l (sp)+,d3-d7/a3-a6 * レジスタ復帰
rts
*------------------------------------
* d1.w=スキャンコード
* d0.w=シフト状態
TJTable:
* jump先(offset),code
.dc.w LT_SPC-$,SKspc
.dc.w LT_CR-$,SKcr * メインキー
.dc.w LT_CR-$,SKent * テンキー
.dc.w LT_ESC-$,SKesc
.dc.w LT_CLR-$,SKclr
.dc.w LT_MODE-$,SKf1
.dc.w LT_REVMODE-$,SKf5
* 以下はカーソル移動キー
.dc.w LT_UNDO-$,SKundo
.dc.w LT_LEFT-$,SKleft
.dc.w LT_UP-$,SKup
.dc.w LT_RIGHT-$,SKright
.dc.w LT_DOWN-$,SKdown
.dc.w LT_TAB-$,SKtab
.dc.w LT_DEL-$,SKdel
.dc.w LT_HOME-$,SKhome
.dc.w 0,0 * end of table
*------------------------------------
SetWakuH:
* 枠の初期状態設定(半角モード用)
move.l #$0008_0008,d0 * wx,wy = 8,8
bra.s @f
*
SetWaku:
* 枠の初期状態設定(普通モード用)
move.l #$0008_0010,d0 * wx,wy = 8,16
@@: lea txarg(pc),a1
move.l d0,6(a1) * wx,wy
*
moveq.l #-1,d1
moveq.l #-1,d2
IOCS _B_CONSOL * -> d1.h.w=x-offset , d1.l.w=y-offset
move.w xy0+2(pc),d0 * y
lsl.w #4,d0 * y*16
add.w d1,d0 * +y-offset
move.w d0,4(a1)
swap d1
move.w xy0(pc),d0 * x
lsl.w #3,d0 * x*8
add.w d1,d0 * +x-offset
move.w d0,2(a1)
move.w #2,(a1) * text plane2
rts
WakuRev:
* 枠反転
* d0.l 破壊
lea txarg(pc),a1
eor.w #$ffff,10(a1) * 枠パターン反転
IOCS _TXBOX
rts
*
Waku:
* 元カーソル位置枠描画
* d0.w <- 枠パターン
* d0.l 破壊
lea txarg(pc),a1
move.w d0,10(a1) * 枠パターン
IOCS _TXBOX
rts
*------------------------------------
* その他
LT_REVMODE: * 反転文字読みとりモード設定(押す度にモード反転)
GMDAPI0 GMD_ReadVer * バージョン読み取り
cmp.w #$0104,d0
bcs @f * <V1.4なので無効
moveq.l #-1,d1 * 現在のモード読み取り
GMDAPI0 GMD_RevMode * d0.l=$00/$FF
not.b d0 * ->$FF/$00
move.l d0,d1
GMDAPI0 GMD_RevMode * d0.l=$00/$FF
@@: rts
LT_MODE: * 読みとりモード設定
* ASKがない時は無効(ASKの内部ルーチンを使うから)
tst.b fask
bne 10f * ASKがない
*
moveq.l #0,d0 * 枠パターン:消去
bsr Waku * 一旦枠を消す
MODE_SET:
eor.b #$ff,mode * モード反転
beq NormalWaku * on -> off
* off-> on : 半角モード
bsr SetWakuH
move.w #$5555,d0 * 枠パターン
bsr Waku * 初期枠
* V1.1
moveq.l #0,d1
lea CurPTRN(pc),a1 * カーソル形状
IOCS _DEFCHR * カーソル形状設定
10: rts
NormalWaku: * 普通モード
bsr SetWaku
move.w #$cccc,d0 * 枠パターン
CurWaku: * カーソル戻して枠設定(V1.12)
bsr Waku * 初期枠
moveq.l #-1,d1 * V1.1
IOCS _DEFCHR * カーソル形状戻し
rts
LT_CLR: * キーバッファークリア
and.w #SKsft,d0
beq @f * CLRのみ -> 何もしない
BEEP
KSDAPI0 KSD_Clear
@@: rts
*------------------------------------
* 読み取り処理
LT_SPC: * 1文字取得
moveq.l #-1,d6 * カーソルはすでに移動されているの印
move.w d0,d1
and.w #SKctrl,d0
beq @f * ->SPCで1文字読みとり/OPT.1+SPCで全画面読み取り
* CTRL+SPC:単語一気読みとり
moveq.l #-1,d1 * 現在カーソル位置から
GMDAPI0 GMD_ReadTango * カーソルも移動する
tst.l d0
beq err
rts
*
@@: and.w #SKopt1,d1
bne ALLGET * ->全画面書き出し
* SPC:1文字読み込み
* 1文字読み込み
moveq.l #-1,d1 * 現在カーソル位置から
GMDAPI0 GMD_Read1 * -> d0.l
move.l d0,d1 * 保存
swap d1 * d1.w=幅
GMDAPI0 GMD_MoveCursor * カーソル移動
swap d1 * d1.w=文字
cmp.w #NOCHR,d1
bne @f
err: BEEP * 読み取れなかった
rts
@@: * 読み取れた
bsr Writer0 * 書き込み(d1.w)
rts
*
*
ALLGET: * OPT.1+SPC:全画面書き出し
* ここの処理において、GMDのWriterの変更で書き出ししても良いが、
* Writerは初期化時に別ルーチンに設定されているので、
* ここで再設定するのが面倒なのでやめている。
*
* ファイルオープン
* ここの処理はfopen(OutFile,"at+")の処理と同じである。
* 汎用的に使えるような気がする。
move.w #RWOPEN,-(sp) * 読み書きモード
pea OutFile(pc)
DOS _OPEN
addq.w #6,sp
tst.l d0
bmi create
* ファイルがオープン出来た
move.w d0,fp * fp記録
* ファイルの最後-1に移動する
move.w #SEEK_END,-(sp)
move.l #-1,-(sp) * offset=-1
move.w fp,-(sp)
DOS _SEEK
DOS _FGETC * 最後の1文字を読む(fpはすでに積まれている)
cmp.b #EOF,d0 * $1aがある?
bne @f * ない=このまま追記
* EOFを消すためもう一度ファイルの最後に移動する(引数はすでにスタック上にある)
DOS _SEEK
@@: addq.w #8,sp
bra 10f
*
create: * OPEN出来ない~新規ファイルかも知れない
move.w #FA_ARCH,-(sp)
pea OutFile(pc)
DOS _CREATE
addq.w #6,sp
tst.l d0
bmi err * CREATEも出来ない=エラー
move.w d0,fp * fp記録
*
10: moveq.l #0,d1 * x=0(h.w),y=0(l.w)から
*
12: GMDAPI0 GMD_Read1 * 1文字読み込み
swap d0 * d0.h.w->d0.l.w=文字幅
swap d1 * d1.l.w=x
add.w d0,d1 * カーソル移動(x+=文字幅)
swap d0 * d0.l.w=文字
* 書き出し
cmp.w #NOCHR,d0
bne @f
move.w #SPC,d0 * 読み取れない文字はスペース化
@@: bsr FileWT * ファイル書きだし(d0.w)
*
cmp.w d5,d1 * 1行分終了?(d5.l.w=CSRXMAX)
bhi @f * Yes(>wx-1)
* 1行内
swap d1
bra 12b
*
@@: * 1行終了
move.w #$0d0a,d0 * 改行を出力(CR+LF)
bsr FileWT
*
clr.w d1 * x=0
swap d1 * x->d1.h.w
addq.w #1,d1 * y+1
cmp.w CSRYMAX,d1 * 全行終了?
bls 12b * No(<=wy-1)
*
move.w fp,-(sp) * ファイルを閉じる
DOS _CLOSE
addq.w #2,sp
BEEP * 終了の合図
bra LT_CR * カーソル戻してGMojiを即終了する
*
*
FileWT: * ファイル書き込みルーチン
* d0.l,d2.w破壊
move.w d0,d2 * push d0
cmp.w #255,d2
bls 1f * 1バイト文字
* 2バイト文字である
* 分割して出力
move.w d0,-(sp)
move.b (sp)+,d0 * d0.l.h.b -> d0.l.l.b
bsr 1f * 上位バイト出力
move.b d2,d0 * 下位バイト出力
1: move.w fp,-(sp)
move.w d0,-(sp)
DOS _FPUTC
addq.w #4,sp
* moveq.l #0,d0 * ok
rts
*
* 1行分メモリー上に取り込んで一気に書き出した方が良いような気もするが、
* ワークがもったいないので今回はパス。ワークはテキスト1行最大128文字
* なので、それが全部1/2,1/4角文字の場合を想定して128*2バイト必要である。
*
*------------------------------------
* カーソル移動
* d6.l = CSRY|CSRX
* d5.l = CSRYMAX|CSRXMAX
LT_ESC: * 終了
* キーボードバッファーをクリアして終了
KSDAPI0 KSD_Clear
LT_CR: * 終了
moveq.l #-1,d7
LT_UNDO:* カーソルを元の位置に戻す
move.l xy0(pc),d6 * x|y
swap d6 * y|x(他に合わせるため)
rts
LT_HOME: * カーソルホーム
moveq.l #0,d6 * x=y=0
rts
LT_DEL: * カーソルエンド
move.l d5,d6 * x=xm,y=ym
rts
LT_LEFT:
and.w #SKctrl,d0
beq @f * LEFTのみ
* CTRL+LEFT : 左端
clr.w d6 * x=0
rts
*
@@: subq.w #1,d6 * x--
bge 2f * >=0 -> ret
move.w d5,d6 * 画面左端x=0->右端x=xm & y-1
LT_UP:
swap d6 * y
subq.w #1,d6 * y--
bge @f * >=0 -> ret
swap d5 * ym
move.w d5,d6 * 画面最上y=0->最下y=ym
* swap d5
@@: swap d6
2: rts
LT_RIGHT:
move.w d0,d1
and.w #SKsft,d0
bne LT_TAB * SHIFT+→=TAB
and.w #SKctrl,d1
beq @f * CTRLなし
* CTRL-RIGHT : 右端
move.w d5,d6 * x=xm
rts
*
LT_TAB:
and.w #SKopt1,d0
bne LT_CR * Opt.1+TAB -> 終了
and.w #$fff8,d6 * $fff8=(d6.w/8)*8
addq.w #8,d6
@@: * RIGHTのみ
addq.w #1,d6 * x++
cmp.w d5,d6 * x<=xm?
bls 3f * yes -> ret
clr.w d6 * 画面右端x=xm->左端x=0 & y+1
LT_DOWN:
swap d6 * y
swap d5 * ym
addq.w #1,d6 * y++
cmp.w d5,d6 * y<=ym?
bls @f * yes -> ret
clr.w d6 * 画面最下y=ym->最上y=0
@@: swap d6
* swap d5
3: rts
*********************************************************************
Writer:
* 1文字書き込みルーチン -> KSD
* 主にGMDから呼び出される
move.w 4+2(sp),d1 * cc=文字コード
Writer0:
cmp.w #$ff,d1 * cc>$ff?
bls @f * no
* 2byte code
tst.b mode * 普通モード?
beq 2f * Yes
* 半角モード(ASKが無い時は来ない)
* 全角->半角:変換できないものは消す
bsr kacnv * d1.w -> d1.w (d0/d2/a0破壊)
tst.w d1 * 変換不可?
beq 3f * Yes -> 変換不可は消す
* 実は変換結果が2バイトのこともある(濁点処理)ので2バイト書き込みする
* $00xxの時は00は書き込んでもKSDで消されるので問題なし
2: move.b d1,d2 * 保存
lsr.w #8,d1
KSDAPI0 KSD_Write1 * d1.b -> KSD
tst.l d0
bne 1f * ok
move.b d2,d1 * 復帰
@@: KSDAPI0 KSD_Write1 * d1.b -> KSD
tst.l d0
beq 3f * ok
1: * Yes : これ以上は書き込めない(KSD Full)
BEEP * d0,d1破壊
moveq.l #1,d0 * return(1)
3: rts
*********************************************************************
kacnv:
* 全角->半角変換
* d1.w <- 全角文字
* -> d1.w ($??xx:半角文字) , $0000=変換不可
* d0,a0破壊
lea work(pc),a0
move.w d1,(a0)
clr.b 2(a0) * 0,1=文字 , 2=EOS
*
pea (a0)
pea (a0) * 絶対に同じか短くなるので上書きする
pea 14.w * 全角→半角文字列変換
DOS _KNJCTRL
lea 12(sp),sp
*
move.b 1(a0),d0
beq @f * ??00 = 半角化された
* 半角化しても2文字になることがあるのでチェック
cmp.b #'゙',d0 * 濁点
beq 1f
cmp.b #'゚',d0 * 半濁点
beq 1f
* 変換不可 : 全角のまま
moveq.l #0,d1
rts
@@: * 半角1文字
moveq.l #0,d1 * for .b = .w
move.b (a0),d1
rts
1: * 仮名1文字+(半)濁点
move.w (a0),d1
rts
*********************************************************************
* ワーク2
*********************************************************************
* ここに置くワークは、常駐後に使われるもの
* これらのワークエリアは常駐後に利用可能になるので、
* 以下の非常駐ルーチンからは参照しないこと
*------------------------------------------------------------------------------
* オフセットテーブルの定義
.offset 0
*---------------------------------------
_fp .ds.w 1 * ファイルポインタ
_xy0 .ds.l 1 * 最初のカーソル位置
_Wt .ds.l 1 * GMD 元Writer
_Gp .ds.l 1 * GMD 元Group
_msc .ds.w 1 * マウスカーソル表示モード
_tm0 .ds.l 1 * 初期時間
_txarg .ds.w 6 * TXBOX引数
_curptrn .ds.w 16 * カーソル形状
_brksts .ds.w 1 * BREAK状態
.even
_work .ds.b 2+1 * 全角->半角文字変換ワーク(2+EOS+even)
_fask .ds.b 1 * ASK存在フラグ($00=あり,!=なし)
.even
_KEEP_END: * 常駐部分最後
*------------------------------------------------------------------------------
* 実際のワークエリアの定義
*------------------------------------------------------------------------------
.text * .offset解除
work2:
fp equ work2+_fp
xy0 equ work2+_xy0
Wt equ work2+_Wt
Gp equ work2+_Gp
msc equ work2+_msc
tm0 equ work2+_tm0
txarg equ work2+_txarg
curptrn equ work2+_curptrn
brksts equ work2+_brksts
work equ work2+_work
fask equ work2+_fask
* 常駐部分最後
KEEP_END equ work2+_KEEP_END
*********************************************************************
* 非常駐ルーチン
*********************************************************************
* この中ではa0は壊さないこと(プロセス管理ポインタを参照するため)
.even
chkarg: * コマンドライン解析(a2=コマンドライン)
tst.b (a2)+ * コマンドラインサイズ = 0?
beq eos * Yes : 引数がない
arglp: bsr skipsp * 空白飛ばし
tst.b d0 * end?
beq eos * Yes
* オプションは -? or /?
cmp.b #'-',d0
beq chkopt
cmp.b #'/',d0
bne arglp
chkopt: * オプションチェック
addq.w #1,a2 * skip '-' or '/'
move.b (a2)+,d0
beq usage * -/のみでオプションがない
or.b #$20,d0 * 小文字化
lea flags-2(pc),a6 * 後で+2するため-2しておく
@@: addq.w #2,a6
tst.b 1(a6)
beq usage * 全オプションチェック終わり -> 規定外オプション
tst.b (a6) * すでにフラグがセットされている?
bne @b * Yes : 飛ばす(2重指定だからbne usageにしてもいい)
cmp.b 1(a6),d0 * オプションチェック
bne @b * 不一致
st.b (a6) * セット
bra arglp * コマンドライン処理へ戻る
skipsp: * 空白飛ばし
move.b (a2)+,d0
cmp.b #' ',d0
beq skipsp
cmp.b #$09,d0 * TAB
beq skipsp
subq.w #1,a2 * a2が1つ進んでいるので戻す
eos: rts
*********************************************************************
* メイン
*********************************************************************
.xref keepchk
.xref _KSDSetAPI
.xref KSDCallAPI
.xref _GMDSetAPI
.xref GMDCallAPI
main:
lea.l initsp(pc),sp * PROGRAM=の時のため
pea title(pc) * タイトル表示
DOS _PRINT
*
move.l #(id-KEEP_START),-(sp) * 識別子の相対位置
pea.l (a0) * 自分のメモリ管理ポインタ
bsr keepchk * 常駐チェック
lea 4*3(sp),sp
move.b d0,d7 * d7 :0=常駐してない , -1=常駐している
bsr chkarg * コマンドライン引数チェック
tst.b rflag * -r : 常駐解除?
beq keep * no
*
* 常駐解除
*
tst.b d7 * 常駐している?
beq Err_NoKp * No -> error
* a0=常駐しているルーチンのメモリ管理ポインタ
pea.l MPSIZ(a0)
DOS _MFREE * 自己プロセスメモリー解放
addq.w #4,sp
tst.l d0
bmi Err_Kai * なぜかメモリー解放出来ない時
bsr SetAPI * API設定&アドレス保存
* KSDの外部起動プログラムを解除する
lea ExtFunc(pc),a2
KSDAPI KSD_UnlinkEFunc
tst.l d0
bne Err_Kai * その起動キーで起動されるプログラムが存在しない
*(あり得ないけど)
* KSD/GMDを常駐アンロックする
KSDAPI KSD_JUnlock
GMDAPI GMD_JUnlock
* 常駐解除正常終了
pea.l MesRelease(pc)
DOS _PRINT
addq.w #4,sp
clr.w -(sp) * exit(0)
DOS _EXIT2
*
* 常駐
*
keep:
tst.b d7 * 常駐している?
bne Err_Dbl * Yes -> error(2重常駐)
* KSD/GMDを常駐ロックする
bsr SetAPI * API設定&アドレス保存
KSDAPI KSD_JLock
GMDAPI GMD_JLock
* KSDの外部起動プログラムとして登録する
lea ExtFunc(pc),a2
KSDAPI KSD_LinkEFunc
tst.l d0
bne Err_UseKey * 起動キーがすでに使われている
*
* 組み込みOK
pea MesKeep(pc)
DOS _PRINT
clr.w -(sp) * exit(0)相当
pea (KEEP_END-KEEP_START).w
DOS _KEEPPR
*
*
SetAPI: * API設定&アドレス保存
* すでに常駐している状態でこの処理を走らせてはいけない(それがV1.2迄のバグ)
* KSD check
movem.l a0/a2,-(sp)
jsr _KSDSetAPI
movem.l (sp)+,a0/a2
tst.l d0
beq Err_NoKSD
move.l d0,AdKSDAPI
* GMD check
movem.l a0/a2,-(sp)
jsr _GMDSetAPI
movem.l (sp)+,a0/a2
tst.l d0
beq Err_NoGMD
move.l d0,AdGMDAPI
rts
*
* エラー終了
*
Err_UseKey: * 起動キーがすでに使われている
KSDAPI KSD_JUnlock * KSDとGMDがロックされているので解除
GMDAPI GMD_JUnlock
lea.l ErrUseKey(pc),a0
bra.s error
Err_NoKSD: * KSDがない
lea.l ErrNoKSD(pc),a0
bra.s error
Err_NoGMD: * GMDがない
lea.l ErrNoGMD(pc),a0
bra.s error
Err_NoKp: * 常駐していないのに解除しようとした
lea.l NoKeep(pc),a0
bra.s error
Err_Dbl: * 2重常駐
lea.l AlreadyKeep(pc),a0
bra.s error
Err_Kai: * 常駐解除不可
lea.l CantRelease(pc),a0
bra.s error
usage: * 使用法
lea.l MesUsage(pc),a0
error: move.w #2,-(sp) * STDERR
pea.l (a0)
DOS _FPUTS * 表示
addq.w #2+4,sp
move.w #2,-(sp) * exit(2)
DOS _EXIT2
******************************************************************************
* メッセージなど
******************************************************************************
.even
title: .dc.b 'GMoji V1.4 Copyright 1997-98,2000 by AIG-Soft'
* .dc.b $0d,$0a,$09,'Debug中 001' * CrLfにつながる
CrLf .dc.b $0d,$0a,0
MesKeep: .dc.b '常駐しました',$0d,$0a,0
MesRelease: .dc.b '常駐解除しました',$0d,$0a,0
NoKeep: .dc.b '常駐していません',$0d,$0a,0
AlreadyKeep: .dc.b 'すでに常駐しています',$0d,$0a,0
CantRelease: .dc.b '常駐解除できません',$0d,$0a,0
ErrNoKSD .dc.b 'KSDが組み込まれていません',$0d,$0a,0
ErrNoGMD .dc.b 'GMDが組み込まれていません',$0d,$0a,0
ErrUseKey .dc.b '起動キー[Opt.1+TAB]が他のプログラムで使われています',$0d,$0a,0
MesUsage: .dc.b 'GMoji [/R]',$0d,$0a,0
.even
flags: * work,フラグキャラクター
rflag .dc.b 0,'r' * 常駐解除フラグ
.dc.b 0,0 * end of table
******************************************************************************
* 非常駐ルーチンが使うスタック
******************************************************************************
.stack
.even
.ds.l 512
initsp:
******************************************************************************
.end main